// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


#pragma once

#include <string>

#include <melon/range.h>
#include "melon/dynamic.h"

namespace kumo::pollux::functions {
    /**
     * Extract a json object from path
     * @param json: A json object
     * @param path: Path to locate a json object. Following operators are supported
     *              "$"      Root member of a json structure no matter it's an
     *                       object or an array
     *              "./[]"   Child operator to get a children object
     *              "[]"     Subscript operator for array and map
     *              "*"      Wildcard for [], get all the elements of an array
     * @return Return json string object on success.
     *         On invalid json path, returns melon::none (not json null) value
     *         On non-json value, returns the original value.
     * Example:
     * For the following example: ,
     * "{\"store\":,
     *   {\"fruit\":\\[{\"weight\":8,\"type\":\"apple\"},
     *                 {\"weight\":9,\"type\":\"pear\"}],
     *    \"bicycle\":{\"price\":19.95,\"color\":\"red\"}
     *   },
     *  \"email\":\"amy@only_for_json_udf_test.net\",
     *  \"owner\":\"amy\",
     * }",
     * jsonExtract(json, "$.owner") = "amy",
     * jsonExtract(json, "$.store.fruit[0]") =
     *    "{\"weight\":8,\"type\":\"apple\"}",
     * jsonExtract(json, "$.non_exist_key") = NULL
     * jsonExtract(json, "$.store.fruit[*].type") = "[\"apple\", \"pear\"]"
     */
    melon::Optional<melon::Dynamic> jsonExtract(
        melon::StringPiece json,
        melon::StringPiece path);

    melon::Optional<melon::Dynamic> jsonExtract(
        const melon::Dynamic &json,
        melon::StringPiece path);

    melon::Optional<std::string> jsonExtractScalar(
        melon::StringPiece json,
        melon::StringPiece path);

    melon::Optional<melon::Dynamic> jsonExtract(
        const std::string &json,
        const std::string &path);

    melon::Optional<std::string> jsonExtractScalar(
        const std::string &json,
        const std::string &path);
} // namespace kumo::pollux::functions
